from django.shortcuts import render
from django.http import QueryDict
# Create your views here.

from api.models import *

from django.views import View
import json
import time
import datetime
from django.http import JsonResponse, HttpRequest
from django.core import serializers
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.forms import model_to_dict
from django.core.exceptions import ObjectDoesNotExist
from django.urls import resolve


class MyJSONEncoder(json.JSONEncoder):
    def default(self, field):
        if isinstance(field, datetime.datetime):
            return field.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(field, datetime.date):
            return field.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self, field)





@method_decorator(csrf_exempt, name="dispatch")
class BaseView(View):
    def __init__(self):
        self.url_name = ''
        self.page = 1
        self.limit = 10
        self.slice = slice(0, 10)
        self.count = 0

        self.resp = {
            'code': 0,
            'msg': '',
            'data': None,
            'count': 0,
        }

    def set_resp(self, resp={}):
        self.resp.update(resp)
        return self

    def parse_body(self, request):
        content_type = request.META.get('CONTENT_TYPE')
        if content_type == 'application/json':
            return json.loads(request.body.decode("utf-8"))
        elif content_type == 'application/x-www-form-urlencoded':
            querydict = QueryDict(
                request.body.decode("utf-8"), encoding="utf-8")
            response_dict = {}
            try:
                for key, val in querydict.items():
                    response_dict[key] = val
            except:
                pass
            return response_dict
        else:
            return request.body

    def json(self, status=200):
        self.resp['code'] = 200
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=status)

    def json_400(self):
        self.resp['code'] = 400
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=400)

    def json_401(self):
        self.resp['code'] = 401
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=401)

    def json_403(self):
        self.resp['code'] = 403
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=403)

    def json_404(self):
        self.resp['code'] = 404
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=404)

    def json_201(self):
        self.resp['code'] = 201
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=201)

    def json_204(self):
        self.resp['code'] = 204
        return JsonResponse(data=self.resp, encoder=MyJSONEncoder, status=204)

    def dispatch(self, request, *args, **kwargs):
        self.url_name = resolve(request.path).url_name
        self.page = int(request.GET.get('page', self.page))
        self.limit = int(request.GET.get('limit', self.limit))
        self.slice = slice(self.limit * (self.page - 1),
                           self.limit * self.page)
        result = super().dispatch(request, *args, **kwargs)
        return result


class TagView(BaseView):
    def get(self, request, **kwargs):
        pk = kwargs.get('id')
        if pk:
            try:
                tag = Tag.objects.get(pk=pk)
                return self.set_resp({
                    'data': model_to_dict(tag),
                    'count': 1
                }).json()
            except ObjectDoesNotExist:
                return self.json_404()
        else:
            data = list(Tag.objects.values()[self.slice])
            count = Tag.objects.count()
            return self.set_resp({
                'data': data,
                'count': count,
            }).json()

    def post(self, request, **kwargs):
        if not self.url_name == 'tags':
            return self.json_400()
        name = request.POST.get("name", "")
        if not name:
            return self.set_resp({
                'code': 400,
                'msg': '为传入name'
            }).json_400()
        tag = Tag.objects.create(**{
            'name': name
        })
        return self.set_resp({
            'data': model_to_dict(tag)
        }).json_201()

    def put(self, request, **kwargs):
        if self.url_name == 'tags':
            return self.json400()
        pk = kwargs.get('id')
        if pk:
            put = self.parse_body(request)
            name = put.get("name", "")
            if not name:
                return self.set_resp({
                    'code': 400,
                    'msg': '为传入name'
                }).json_400()
            tag = Tag.objects.get(pk=pk)
            tag.name = name
            tag.save()
            return self.set_resp({
                'data': model_to_dict(tag)
            }).json()

        else:
            return self.json_400()

    def patch(self, request, **kwargs):
        return self.put(request, **kwargs)

    def delete(self, request, **kwargs):
        if self.url_name == 'tags':
            return self.json_400()
        pk = kwargs.get('id')
        if pk:
            try:
                tag = Tag.objects.get(pk=pk).delete()
                return self.json_204()
            except:
                return self.json_404()
        else:
            return self.json_400()
